package com.tax.config.redisConfig.redisoperator;

import com.tax.config.redisConfig.rediscondition.RedisObjectCondition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 当模板类型序列化为Object时提供操作类
 * @Author wjd
 * @Date 2020/4/22 10:51
 **/
@Conditional(RedisObjectCondition.class)
@Component
public class RedisOperatorObjectService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * @Author: wjd
     * @Description: 根据 key 值获取该缓存剩余过期时间
     * @Remark: 实现命令: TTL key,以秒为单位,返回给定 key的剩余生存时间(TTL, time to live)
     * @Date: 2020/4/21 17:04
     **/
    public long ttl(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * @Author: wjd
     * @Description: 给定一个 key 值设置过期时间(单位:秒)
     * @Remark: 实现命令: expire timeout
     * @Date: 2020/4/21 17:06
     **/
    public void expire(String key, long timeout) {
        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * @Author: wjd
     * @Description: 为指定的 key 值进行增加
     * @Remark: 实现命令: INCRBY key delta
     * @Date: 2020/4/21 17:08
     **/
    public long incr(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * @Author: wjd
     * @Description: 为指定的 key 值进行递减
     * @Remark: 实现命令: DECRBY key delta
     * @Date: 2020/4/21 17:11
     **/
    public long decr(String key, long delta) {
        if(delta<0){
            //throw new RuntimeException("递减因子必须大于0");
            del(key);
            return 0;
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * @Author: wjd
     * @Description: 查找所有符合给定模式 pattern的 key
     * @Remark: 实现命令: KEYS pattern
     * @Date: 2020/4/21 17:21
     **/
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * @Author: wjd
     * @Description: 删除当前 key
     * @Remark: 实现命令: DEL key
     * @Date: 2020/4/21 17:23
     **/
    public void del(String key) {
        redisTemplate.delete(key);
    }

    /**
     * @Author: wjd
     * @Description: 为 key 值设定一个对应的 value 值(无过期时间)
     * @Remark: 实现命令: SET key value
     * @Date: 2020/4/21 17:24
     **/
    public void setString(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public void setObject(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * @Author: wjd
     * @Description: 为key值设定一个对应的 value 值(带过期时间,单位为秒)
     * @Remark: 实现命令: SET key value EX timeout
     * @Date: 2020/4/21 17:29
     **/
    public void setString(String key, String value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    public void setObject(String key, Object value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * @Author: wjd
     * @Description: 根据 key 值获取所关联的 value 值
     * @Remark: 实现命令: GET key
     * @Date: 2020/4/21 17:31
     **/
    public String getString(String key) {
        return (String) redisTemplate.opsForValue().get(key);
    }

    public Object getObject(String key) {
        return redisTemplate.opsForValue().get(key);
    }


    /**
     * @Author: wjd
     * @Description: 将哈希表 key 中的字段 field 的值设为 value
     * @Remark: 实现命令: HSET key field value
     * @Date: 2020/4/21 17:32
     **/
    public void hsetString(String key, String field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    public void hsetObject(String key, String field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    /**
     * @Author: wjd
     * @Description: 返回哈希表 key中给定域 field的值
     * @Remark: 实现命令: HGET key field
     * @Date: 2020/4/21 17:36
     **/
    public String hgetString(String key, String field) {
        return (String) redisTemplate.opsForHash().get(key, field);
    }

    public Object hgetObject(String key, String field) {
        return redisTemplate.opsForHash().get(key, field);
    }

    /**
     * @Author: wjd
     * @Description: 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略
     * @Remark: 实现命令: HDEL key field [field ...]
     * @Date: 2020/4/21 17:38
     **/
    public void hdel(String key, Object... fields) {
        redisTemplate.opsForHash().delete(key, fields);
    }

    /**
     * @Author: wjd
     * @Description: 返回哈希表 key 中所有的域和值
     * @Remark: 实现命令: HGETALL key
     * @Date: 2020/4/21 17:39
     **/
    public Map<Object, Object> hgetall(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * @Author: wjd
     * @Description: 将一个值 value 插入到列表 key的表头
     * @Remark: 实现命令: LPUSH key value
     * @Date: 2020/4/21 17:41
     **/
    public long lpushString(String key, String value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }

    public long lpushObject(String key, Object value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * @Author: wjd
     * @Description: 移除并返回列表 key 的头元素
     * @Remark: 实现命令: LPOP key
     * @Date: 2020/4/21 17:43
     **/
    public String lpop(String key) {
        return (String) redisTemplate.opsForList().leftPop(key);
    }

    /**
     * @Author: wjd
     * @Description: 将一个值 value插入到列表 key的表尾(最右边)
     * @Remark: 实现命令: RPUSH key value
     * @Date: 2020/4/21 17:43
     **/
    public long rpushString(String key, String value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }

    public long rpushObject(String key, Object value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }
}
